﻿using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;
using RgCore.Menu;
using System;
using System.Collections.Generic;

namespace CustomCharacter.Ability
{
    public enum AbilityTrigger
    {
        Active,
        Update,
        Active_Update,
        Event,
        Deactive
    }
    public enum AbilityType
    {
        Offensive,
        Passive,
        Attribute
    }

    public readonly struct AbilityOutput
    {
        public AbilityOutput(bool success, string response = "") : this(success, false, 0, response)
        {
        }

        public AbilityOutput(bool success, bool setvaluemode, int duration, string response)
        {
            Success = success;
            SetValueMode = setvaluemode;
            ActivationChange = duration;
            Response = response;
        }
        public static implicit operator AbilityOutput(bool source)
        {
            return new AbilityOutput(source);
        }

        /// <summary>
        /// 是否成功使用
        /// </summary>
        public readonly bool Success;

        /// <summary>
        /// 设置值模式
        /// </summary>
        public readonly bool SetValueMode;

        /// <summary>
        /// 激活状态时间改变，若SetValueMode为true，该数<=0代表无变化，>0代表激活时间
        /// ，若为false，该数为激活时间变化量
        /// </summary>
        public readonly int ActivationChange;

        public readonly string Response;
    }

    public delegate AbilityOutput AbilityDelegate(Player player, ref AbilityInfo info, IExiledEvent e, AbilityTrigger trigger);

    /// <summary>
    /// 角色技能
    /// </summary>
    public class Ability
    {
        public Ability(string id, string description, AbilityType type, uint cooldown, AbilityDelegate abilityFunc,
            InstanceConditionResponse<Player> checker, IEnumerable<IExiledEvent> events,
            KeyValuePair<string, object>[] dataargs, params Type[] belonging)
        {
            AbilityId = id;
            Type = type;
            Description = description;
            Cooldown = cooldown;
            Condition = checker;
            Belongings = belonging;
            DataArgs = dataargs;
            Function = abilityFunc;
            ToRegisteredEvent = events;
        }

        /// <summary>
        /// 技能ID，唯一标识符
        /// </summary>
        public string AbilityId { get; }

        /// <summary>
        /// 技能描述
        /// </summary>
        public string Description { get; }

        /// <summary>
        /// 技能类型
        /// </summary>
        public AbilityType Type { get; }
        /// <summary>
        /// 冷却模块
        /// </summary>
        public uint Cooldown { get; }

        /// <summary>
        /// 指定角色的默认技能（会在生成角色时自动给予此技能）
        /// </summary>
        public Type[] Belongings { get; }

        /// <summary>
        /// 技能条件检测（它没有用，它是给CD模块赋值的）
        /// </summary>
        public InstanceConditionResponse<Player> Condition { get; }

        /// <summary>
        /// 技能数据参数名
        /// </summary>
        public KeyValuePair<string, object>[] DataArgs { get; }

        public string Text
        {
            get
            {
                string color = "#FFFFFF";
                string text = "未知";
                switch(Type)
                {
                    case AbilityType.Offensive:
                        text = "主动";
                        color = "yellow";
                        break;
                    case AbilityType.Passive:
                        text = "被动";
                        color = "#05A3AD";
                        break;
                    case AbilityType.Attribute:
                        text = "特性";
                        color = "#FF00FF";
                        break;
                }
                return $"<color={color}>{text}</color>";
            }
        }

        public IEnumerable<IExiledEvent> ToRegisteredEvent { get; }

        public AbilityDelegate Function { get; }
    }

    public class AttributeAbility : Ability
    {
        public AttributeAbility(string id, string description, AbilityDelegate function, bool update, IEnumerable<IExiledEvent> events, 
            KeyValuePair<string, object>[] dataargs, params Type[] belonging) : 
            base(id, description, AbilityType.Attribute, 0, function, null, events, dataargs, belonging)
        {
            Update = update;
        }

        public bool Update { get; }
    }
}